package pe.edutec.app.layer.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import pe.edutec.app.domain.Curso;
import pe.edutec.app.domain.CursoProgramado;
import pe.edutec.app.domain.Matricula;
import pe.edutec.app.layer.dao.interfaces.ProcesosDao;

/**
 *
 * @author Gustavo Coronel
 */
public class ProcesosDaoImpl implements ProcesosDao {

	@Override
	public List<CursoProgramado> leerCursosProg(String ciclo) {
		Connection cn = null;
		List<CursoProgramado> lista = new ArrayList<CursoProgramado>();
		try {
			cn = AccesoDB.getConnection();
			// PreparedStatement para consultar cursos
			String sql = "select idcurso, idtarifa, nomcurso from dbo.curso "
							+ "where idcurso = ?";
			PreparedStatement pstmCurso = cn.prepareStatement(sql);
			ResultSet rsCurso;
			// PreparedStatement para Cursos Programados
			sql = "select idcursoprog, idcurso, idciclo, idprofesor, "
							+ "vacantes, matriculados, precursoprog, horario, activo "
							+ "from dbo.CursoProgramado where idciclo = ?";
			PreparedStatement pstm = cn.prepareStatement(sql);
			pstm.setString(1, ciclo);
			ResultSet rs = pstm.executeQuery();
			while (rs.next()) {
				CursoProgramado cp = rowCursoProgToBean(rs);
				pstmCurso.setString(1, cp.getCurso().getIdCurso());
				rsCurso = pstmCurso.executeQuery();
				rsCurso.next();
				cp.getCurso().setIdTarifa(rsCurso.getString("idtarifa"));
				cp.getCurso().setNombre(rsCurso.getString("nomcurso"));
				rsCurso.close();
				lista.add(cp);
			}
			rs.close();
			pstm.close();
			pstmCurso.close();
		} catch (SQLException e) {
			throw new RuntimeException(e.getMessage());
		} catch (Exception e) {
			throw new RuntimeException("Error al consultar tabla de alumnos.");
		} finally {
			try {
				cn.close();
			} catch (Exception e) {
			}
		}
		return lista;
	}

	private CursoProgramado rowCursoProgToBean(ResultSet rs) throws SQLException {
		CursoProgramado cp = new CursoProgramado();
		cp.setIdCursoProg(rs.getInt("idcursoprog"));
		Curso c = new Curso();
		c.setIdCurso(rs.getString("idcurso"));
		cp.setCurso(c);
		cp.setIdCiclo(rs.getString("idciclo"));
		cp.setIdProfesor(rs.getString("idprofesor"));
		cp.setVacantes(rs.getInt("vacantes"));
		cp.setMatriculados(rs.getInt("matriculados"));
		cp.setPreCursoProg(rs.getDouble("precursoprog"));
		cp.setHorario(rs.getString("horario"));
		cp.setActivo(rs.getInt("activo"));
		return cp;
	}

	@Override
	public void procMatricula(Matricula matricula) {
		// Variables
		Connection cn = null;
		String sql;
		int cont, vacantes;
		PreparedStatement pstm;
		ResultSet rs;
		try {
			cn = AccesoDB.getConnection();
			cn.setAutoCommit(false); // Inicio de la TX
			// Verificar si el alumno ya se encuentra matriculado
			sql = "select count(*) cont from dbo.matricula "
							+ "where IdCursoProg = ? and IdAlumno = ?";
			pstm = cn.prepareStatement(sql);
			pstm.setInt(1, matricula.getIdCursoProg());
			pstm.setString(2, matricula.getIdAlumno());
			rs = pstm.executeQuery();
			rs.next();
			cont = rs.getInt("cont");
			rs.close();
			pstm.close();
			if (cont > 0) {
				throw new SQLException("Alumno ya se encuentra matriculado.");
			}
			// Actualizar las vacantes
			sql = "update dbo.CursoProgramado set vacantes = vacantes - 1, "
							+ "matriculados = matriculados + 1 where idCursoProg = ?";
			pstm = cn.prepareStatement(sql);
			pstm.setInt(1, matricula.getIdCursoProg());
			pstm.executeUpdate();
			pstm.close();
			// Verificar si hay vacantes
			sql = "select vacantes from dbo.CursoProgramado where idCursoProg = ?";
			pstm = cn.prepareStatement(sql);
			pstm.setInt(1, matricula.getIdCursoProg());
			rs = pstm.executeQuery();
			if (!rs.next()) {
				throw new SQLException("No existe el IdCursoProg.");
			}
			vacantes = rs.getInt("vacantes");
			rs.close();
			pstm.close();
			if (vacantes < 0) {
				throw new SQLException("No hay vacantes.");
			}
			// Procede la matricula
			sql = "insert into matricula(IdCursoProg,IdAlumno,FecMatricula,"
							+ "ExaParcial,ExaFinal,Promedio,Subsanacion,ExaSub) "
							+ "values(?,?,getdate(),0,0,0,0,0)";
			pstm = cn.prepareStatement(sql);
			pstm.setInt(1, matricula.getIdCursoProg());
			pstm.setString(2, matricula.getIdAlumno());
			pstm.executeUpdate();
			pstm.close();
			// Confirmar TX
			cn.commit();
		} catch (SQLException e) {
			try {
				cn.rollback();
			} catch (Exception e1) {
			}
			throw new RuntimeException(e.getMessage());
		} catch (Exception e) {
			try {
				cn.rollback(); // Cancela la TX
			} catch (Exception e1) {
			}
			throw new RuntimeException("Error en el proceso de matricula.");
		} finally {
			try {
				cn.close();
			} catch (Exception e) {
			}
		}
	}
}
